package org.jwd.storage.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.jwd.core.entity.AuthEntity;
import org.jwd.core.entity.UserEntity;
import org.jwd.core.web.Req;
import org.jwd.core.web.Res;
import org.jwd.storage.mbp.config.DynamicValidationService;
import org.jwd.storage.service.AuthService;
import org.jwd.storage.service.UserService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;

/**
 * @author vizz
 * @since 2022/5/16 10:11
 */
@Slf4j
@RestController
@RequestMapping("auth")
public class AuthController {

    @Resource
    private AuthService authService;

    @Resource
    private UserService userService;

    @Resource
    private DynamicValidationService dynamicValidationService;

    /**
     * 登陆逻辑
     *
     * @param userInput 输入user_code & password
     * @return res
     */
    @PostMapping("login")
    public Res login(@RequestBody UserEntity userInput, HttpServletRequest request) {

        UserEntity userInfo = userService.getOne(new QueryWrapper<UserEntity>()
                .eq("user_code", userInput.getUserCode()));
        if (userInfo == null) {
            return Res.fail(301, "账号不存在");
        }
        Long userId = userInfo.getId();

        //输错5次密码会被冻结一段时间，这里检查是否被冻结中
        AuthEntity authInfo = authService.getOne(new QueryWrapper<AuthEntity>()
                .eq("user_id", userId));
        if (authInfo != null) {
            LocalDateTime availableTime = authInfo.getLastLoginTime().plusMinutes(30);
            if (authInfo.getType() == 0 && authInfo.getFailCount() >= 5 && LocalDateTime.now().isBefore(availableTime)) {
                return Res.fail(304, String.format("您已输错5次密码，请在 {} 后再试", availableTime));
            }
        } else {
            //表示没登陆过,继续走登陆逻辑
            authInfo = new AuthEntity();
            authInfo.setIp(Req.getClientIpAddress(request)).setType(0).setFailCount(0);
        }
        return checkUserWithPwd(userInput, userInfo, authInfo);
    }

    /**
     * 退出登陆
     *
     * @return res
     */
    @PostMapping("logout/{user-id}")
    public Res logout(@PathVariable("user-id") String userId) {
        boolean res = authService.remove(new QueryWrapper<AuthEntity>()
                .eq("user_id", userId));
        if (!res) {
            log.warn("用户并未登陆，注销失败！请检查数据库，用户id为{}", userId);
        }
        return Res.succeed("", res);
    }


    /**
     * 检查用户名和密码是否正确
     *
     * @param userInput 用户输入的信息
     * @param userInfo  数据库中的用户信息
     * @param authInfo  验证信息
     * @return res
     */
    private Res checkUserWithPwd(UserEntity userInput, UserEntity userInfo, AuthEntity authInfo) {
        String realPwd = userInfo.getPassword();
        //如果有加密，请在这里把realPwd做个解密处理
        //保持authInfo的id为空就是sava，如果不为空就是update
        if (userInput.getPassword().equals(realPwd)) {
            //登陆成功
            dynamicValidationService.addValidationInfo(authInfo);
            authService.saveOrUpdate(authInfo);
            return Res.succeed("登陆成功");
        } else {
            authInfo.setFailCount(authInfo.getFailCount() + 1);
            authService.saveOrUpdate(authInfo);
            return Res.fail(300, String.format("密码错误，还有 {} 次机会", 5 - authInfo.getFailCount()));
        }
    }

}
